<html>
   <head>
      <title>Box2dWeb Demo</title>
   </head>
   <body onload="init();">
      <canvas id="canvas" width="1000" height="800" style="background-color:#333333;" ></canvas>
	  
   </body>
   <script type="text/javascript" src="Box2dWeb-2.1.a.3.min.js"></script>
   <script type="text/javascript">
   
      
      function init() {
         var   b2Vec2 = Box2D.Common.Math.b2Vec2
,   b2AABB = Box2D.Collision.b2AABB
, b2BodyDef = Box2D.Dynamics.b2BodyDef
, b2Body = Box2D.Dynamics.b2Body
, b2FixtureDef = Box2D.Dynamics.b2FixtureDef
, b2Fixture = Box2D.Dynamics.b2Fixture
, b2World = Box2D.Dynamics.b2World
, b2MassData = Box2D.Collision.Shapes.b2MassData
, b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape
, b2CircleShape = Box2D.Collision.Shapes.b2CircleShape
, b2DebugDraw = Box2D.Dynamics.b2DebugDraw
 b2Joint = Box2D.Dynamics.Joints.b2Joint
,   b2MouseJointDef =  Box2D.Dynamics.Joints.b2MouseJointDef
, b2PrismaticJointDef = Box2D.Dynamics.Joints.b2PrismaticJointDef
, b2PrismaticJoint = Box2D.Dynamics.Joints.b2PrismaticJoint
, b2RevoluteJointDef = Box2D.Dynamics.Joints.b2RevoluteJointDef
, b2DistanceJointDef =  Box2D.Dynamics.Joints.b2DistanceJointDef
            ;
		var isKeyPress = false;
         var Vd =  new b2Vec2(0,0);
		 var Impulsed =  new b2Vec2(0,0);
         var world = new b2World(
               new b2Vec2(0, 10)    //gravity
            ,  true                 //allow sleep
         );

         var jump_speed = 0;
         var fixDef = new b2FixtureDef;
         fixDef.density = 0.5;
         fixDef.friction = .5;
         fixDef.restitution = 0.2;
         
         var bodyDef = new b2BodyDef;
         
         //create ground
         bodyDef.type = b2Body.b2_staticBody;
         fixDef.shape = new b2PolygonShape;
         fixDef.shape.SetAsBox(1000/(2*30), 2);
         bodyDef.position.Set(500/30, 800 / 30 + 1.8);
         var floor = world.CreateBody(bodyDef)
		 floor.CreateFixture(fixDef);
		 bodyDef.position.Set(1250/30, 800 / 30 + 1.8);
		 world.CreateBody(bodyDef).CreateFixture(fixDef);
         bodyDef.position.Set(500/30, -1.8);
         world.CreateBody(bodyDef).CreateFixture(fixDef);
         fixDef.shape.SetAsBox(2, 800/(2*30));
         bodyDef.position.Set(-1.8, 400/30);
         world.CreateBody(bodyDef).CreateFixture(fixDef);
         bodyDef.position.Set(1000/30+1.8, 400/30);
         world.CreateBody(bodyDef).CreateFixture(fixDef);
         
		 //create static object
		 bodyDef.type = b2Body.b2_staticBody
			fixDef.shape = new b2PolygonShape;
			fixDef.shape.SetAsBox(200/30,30/30);
			bodyDef.position.x = 500/30
			bodyDef.position.y = 500/30
			var staticbody = world.CreateBody(bodyDef)
			staticbody.CreateFixture(fixDef);
	
	 //create some objects
	 /*
         bodyDef.type = b2Body.b2_dynamicBody;
         for(var i = 0; i < 10; ++i) {
            if(Math.random() > 0.5) {
               fixDef.shape = new b2PolygonShape;
               fixDef.shape.SetAsBox(
                     Math.random() + 0.1 //half width
                  ,  Math.random() + 0.1 //half height
               );
            } else {
               fixDef.shape = new b2CircleShape(
                  Math.random() + 0.1 //radius
               );
            }
            bodyDef.position.x = Math.random() * 10;
            bodyDef.position.y = Math.random() * 10;
            world.CreateBody(bodyDef).CreateFixture(fixDef);
         }
	
	*/
	
         
         //create some objects
         bodyDef.type = b2Body.b2_dynamicBody;
            //if(Math.random() > 0.5) {
               fixDef.shape = new b2PolygonShape;
               fixDef.shape.SetAsBox(1,1 );
            //} else {
            //   fixDef.shape = new b2CircleShape(
            //      Math.random() + 0.1 //radius
            //  );
            //}
            bodyDef.position.x =  5;
            bodyDef.position.y =  5;
            var mybody = world.CreateBody(bodyDef);
			mybody.CreateFixture(fixDef);
			mybody.SetFixedRotation(true);

    //create some objects 2
         bodyDef.type = b2Body.b2_dynamicBody;
            //if(Math.random() > 0.5) {
             fixDef.shape = new b2PolygonShape;
               fixDef.shape.SetAsBox(1,.1 );
            //} else {
            //   fixDef.shape = new b2CircleShape(
            //      Math.random() + 0.1 //radius
            //  );
            //}
            bodyDef.position.x = 5;
            bodyDef.position.y = 6.1;
            var mybody2 = world.CreateBody(bodyDef);
			mybody2.CreateFixture(fixDef);
		/*
	  var myjointdef_dist = new b2DistanceJointDef();
		myjointdef_dist.Initialize(mybody, mybody2, mybody.GetWorldCenter(),mybody2.GetWorldCenter());
		myjointdef_dist.collideConnected = true;
		myjointdef_dist.frequencyHz = 10;
		myjointdef_dist.dampingRatio = 0.1;
		world.CreateJoint(myjointdef_dist);
    */
		var myjointdef = new b2PrismaticJointDef();
			var worldaxis =  new b2Vec2(0,1);
			myjointdef.Initialize(mybody,mybody2,mybody.GetWorldCenter(), worldaxis);
			myjointdef.lowerTranslation = -.01;
			myjointdef.upperTranslation = .02;
			myjointdef.maxMotorForce = 500;
			myjointdef.motorSpeed =  0;
			myjointdef.enableLimit =  true;
			myjointdef.enableMotor =  true;
			var myjoint = world.CreateJoint(myjointdef);
			

         var debugDraw = new b2DebugDraw();

debugDraw.SetSprite(document.getElementById("canvas").getContext("2d"));
debugDraw.SetDrawScale(30.0);
debugDraw.SetFillAlpha(0.5);
debugDraw.SetLineThickness(1.0);
debugDraw.SetFlags(b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit);
world.SetDebugDraw(debugDraw);
         
         window.setInterval(update, 1000 / 60);


         //mouse
         
         var mouseX, mouseY, mousePVec, isMouseDown, selectedBody, mouseJoint;
         var canvasPosition = getElementPosition(document.getElementById("canvas"));
         
         document.addEventListener("mousedown", function(e) {
            isMouseDown = true;
            handleMouseMove(e);
            document.addEventListener("mousemove", handleMouseMove, true);
         }, true);
         
         document.addEventListener("mouseup", function() {
            document.removeEventListener("mousemove", handleMouseMove, true);
            isMouseDown = false;
            mouseX = undefined;
            mouseY = undefined;
         }, true);

document.addEventListener("keydown", function(e) {
e = e || window.event;

var chcode = e.charCode || e.keyCode;
handleKeyPress(chcode);
console.log("keypress: " + chcode );
});

document.addEventListener("keyup",function(e) {
	isKeyPress=false;
});

function handleKeyPress(key) {

var speed = 25;
var speed_impulse = 25;

switch(key) {
case 37:
//left
Vd.x =  -1*speed;
isKeyPress = true;
break;
case 38:
//up
Impulsed.y = -1*speed_impulse; 
isKeyPress = true;
break;
case 39:
//right
Vd.x = 1*speed;
isKeyPress = true; 
break;
case 40:
//down
Impulsed.y = 0*speed_impulse;
isKeyPress = true;
jump_speed = 25;
break;
}

body = mybody;

//if( body != null ) {
//x_pos = body.GetPosition().x;
//y_pos = body.GetPosition().y;

//var n_pos = new b2Vec2(x_pos + dx, y_pos + dy);

//body.SetPosition(n_pos);


//} else {
//console.log("no body found!");
//}
}
         
         function handleMouseMove(e) {
            mouseX = (e.clientX - canvasPosition.x) / 30;
            mouseY = (e.clientY - canvasPosition.y) / 30;
         };
         
         function getBodyAtMouse() {
            mousePVec = new b2Vec2(mouseX, mouseY);
            var aabb = new b2AABB();
            aabb.lowerBound.Set(mouseX - 0.001, mouseY - 0.001);
            aabb.upperBound.Set(mouseX + 0.001, mouseY + 0.001);
            
            // Query the world for overlapping shapes.

            selectedBody = null;
            world.QueryAABB(getBodyCB, aabb);
            return selectedBody;
         }

         function getBodyCB(fixture) {
            if(fixture.GetBody().GetType() != b2Body.b2_staticBody) {
               if(fixture.GetShape().TestPoint(fixture.GetBody().GetTransform(), mousePVec)) {
                  selectedBody = fixture.GetBody();
                  return false;
               }
            }
            return true;
         };
       
function printInfo() {
console.log("body count: "+ world.GetBodyCount()); 
body = null;
body = world.GetBodyList();
body = body.GetNext();
var i = 0;
while( body != null ) {
if( i > 20 ) {
break;
}
console.log("body count: "+ world.GetBodyCount()); 
x = body.GetPosition().x;
y = body.GetPosition().y;

console.log("position [" + i + "]: " + x + "," + y); 
i=i+1;
body = body.GetNext();
}
};

         //update

var i=0;
         
         function update() {

if( i % 2000 == 0) {
console.log("howdy");
printInfo();
}
i++;
			
		 var myvelocity = mybody.GetLinearVelocity() ;
		 var myvelocity2 = mybody2.GetLinearVelocity() ;
		 var myposition = mybody.GetWorldCenter();
		 var myposition2 = mybody2.GetWorldCenter();
		 var staticposition =  staticbody.GetWorldCenter();
		 var mycontactedge = mybody2.GetContactList();
		 /*if(mycontactedge != null){
			var mycontact =  mycontactedge.contact;
			var myfigureA =  mycontact.GetFixtureA();
			if(myfigureA != null){
				var myfigureAbody = myfigureA.GetBody();
				}
		}
		*/
		//myposition2 = b2Vec2(myposition.x,myposition2.y);
		//mybody2.SetTransform(myposition2,0);
		 /*
		 var g_force = new b2Vec2(myposition.x-staticposition.x,myposition.y-staticposition.y);
		 var distance_1 = (g_force.x^2 + g_force.y^2)^-(2)*(g_force.x^2 + g_force.y^2)^-1;
		 g_force = new b2Vec2(-g_force.x*distance_1/10,-g_force.y*distance_1/10);
		 mybody.ApplyForce(g_force,myposition);
		 */
		 
			/*rescues players
			if(myposition.y > 800/30){ 
			mybody.SetPosition(10/30,10/30);
			};
			*/
         if(isKeyPress == true) {
			
			// console.log("objectvelocity: "+ myvelocity) ;
			//myvelocity.Add(Vd);
			//mybody.SetLinearVelocity(myvelocity);
			 
			 /*
			if(Vd.x != 0){
			Vd.x = Vd.x - myvelocity.x/5;
			}
			*/
			mybody.ApplyForce(Vd,myposition);
			myjoint.SetMotorSpeed(jump_speed*10);
			
			if((myvelocity2.y < .01 && myvelocity2.y > -.01) && mycontactedge != null){
				mybody.ApplyImpulse(Impulsed,myposition);
			}
		} else {
			Vd.x=0;
			Vd.y=0;
			Impulsed.x=0;
			Impulsed.y=0;
			jump_speed =  -10;
			myjoint.SetMotorSpeed(jump_speed);
		}
            if(isMouseDown && (!mouseJoint)) {
               var body = getBodyAtMouse();
               if(body) {
                  var md = new b2MouseJointDef();
                  md.bodyA = world.GetGroundBody();
                  md.bodyB = body;
                  md.target.Set(mouseX, mouseY);
                  md.collideConnected = true;
                  md.maxForce = 300.0 * body.GetMass();
                  mouseJoint = world.CreateJoint(md);
                  body.SetAwake(true);
               }
            }
            
            if(mouseJoint) {
               if(isMouseDown) {
                  mouseJoint.SetTarget(new b2Vec2(mouseX, mouseY));
               } else {
                  world.DestroyJoint(mouseJoint);
                  mouseJoint = null;
               }
            }
			
			//magnetism
			var mag_force = new b2Vec2;
			var B_field = 5;
			var charge =  1;
			
			mag_force.x = charge*myvelocity.y*B_field;
			mag_force.y = -charge*myvelocity.x*B_field;
			
			mybody.ApplyForce(mag_force,myposition);
			
            world.Step(1 / 60, 8, 3);
            world.DrawDebugData();
            world.ClearForces();
			
         };
         
         //helpers
         
         //http://js-tut.aardon.de/js-tut/tutorial/position.html
         function getElementPosition(element) {
            var elem=element, tagname="", x=0, y=0;
           
            while((typeof(elem) == "object") && (typeof(elem.tagName) != "undefined")) {
               y += elem.offsetTop;
               x += elem.offsetLeft;
               tagname = elem.tagName.toUpperCase();

               if(tagname == "BODY")
                  elem=0;

               if(typeof(elem) == "object") {
                  if(typeof(elem.offsetParent) == "object")
                     elem = elem.offsetParent;
               }
            }

            return {x: x, y: y};
         }


      };
   
   </script>
   
   
</html>